package com.kotasoft.iip.model.insurance;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import org.codehaus.jackson.map.annotate.JsonView;
import org.joda.time.DateTime;
import org.joda.time.format.ISODateTimeFormat;

import com.kotasoft.iip.model.AuditData;
import com.kotasoft.iip.model.interfaces.HasContract;
import com.kotasoft.iip.serializer.Views;

@Entity
@Table(name = "i_order")
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "TYPE", discriminatorType = DiscriminatorType.CHAR, length = 1)
@SuppressWarnings("serial")
public class Order implements Serializable, HasContract {

	@Id
	@Column(name = "ID", length = 36)
	protected String id;

	@ManyToOne(cascade = CascadeType.DETACH, fetch = FetchType.LAZY, optional = false)
	@JoinColumn(name = "CONTRACT_ID", nullable = false)
	@JsonView(Views.Public.class)
	private Contract contract;

	@Column(name = "AMOUNT", precision = 18, scale = 5)
	@JsonView(Views.Public.class)
	private BigDecimal amount;

	@Column(name = "NET_AMOUNT", precision = 18, scale = 5)
	@JsonView(Views.Public.class)
	private BigDecimal netAmount;

	@Column(name = "EFFECTIVE", nullable = false)
	@Temporal(TemporalType.DATE)
	@JsonView(Views.Public.class)
	private Date effective;

	@Column(name = "VALUE_DATE", nullable = false)
	@Temporal(TemporalType.DATE)
	@JsonView(Views.Public.class)
	private Date valueDate;

	@Column(name = "PROCESSED")
	@Temporal(TemporalType.TIMESTAMP)
	@JsonView(Views.Public.class)
	private Date processed;

	@Column(name = "VALUED")
	@Temporal(TemporalType.TIMESTAMP)
	@JsonView(Views.Public.class)
	private Date valued;

	@Column(name = "ACCOUNTED")
	@Temporal(TemporalType.DATE)
	@JsonView(Views.Public.class)
	private Date accounted;

	@Embedded
	private AuditData auditData;

	@JsonView(Views.ExtendedPublic.class)
	private List<MarketOrder> marketOrders;

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public Contract getContract() {
		return contract;
	}

	public void setContract(Contract contract) {
		this.contract = contract;
	}

	public BigDecimal getAmount() {
		return amount;
	}

	public void setAmount(BigDecimal amount) {
		this.amount = amount;
	}

	public BigDecimal getNetAmount() {
		return netAmount;
	}

	public void setNetAmount(BigDecimal netAmount) {
		this.netAmount = netAmount;
	}

	public Date getEffective() {
		return effective;
	}

	public void setEffective(Date effective) {
		this.effective = effective;
	}

	public Date getValueDate() {
		return valueDate;
	}

	public void setValueDate(Date valueDate) {
		this.valueDate = valueDate;
	}

	public Date getProcessed() {
		return processed;
	}

	public void setProcessed(Date processed) {
		this.processed = processed;
	}

	public Date getValued() {
		return valued;
	}

	public void setValued(Date valued) {
		this.valued = valued;
	}

	public Date getAccounted() {
		return accounted;
	}

	public void setAccounted(Date accounted) {
		this.accounted = accounted;
	}

	public AuditData getAuditData() {
		return auditData;
	}

	public void setAuditData(AuditData auditData) {
		this.auditData = auditData;
	}

	public List<MarketOrder> getMarketOrders() {
		return marketOrders;
	}

	public void setMarketOrders(List<MarketOrder> marketOrders) {
		this.marketOrders = marketOrders;
	}

	public Order withEffective(Date value) {
		effective = value;
		return this;
	}

	@Override
	public String toString() {
		StringBuilder builder = new StringBuilder();
		builder.append("Order [effective=");
		builder.append(effective != null ? ISODateTimeFormat.date().print(new DateTime(effective)) : "<null>");
		builder.append(", processed=");
		builder.append(processed != null ? ISODateTimeFormat.date().print(new DateTime(processed)) : "<null>");
		builder.append(", valued=");
		builder.append(valued != null ? ISODateTimeFormat.date().print(new DateTime(valued)) : "<null>");
		builder.append("]");
		return builder.toString();
	}
}
